/*
 * Feb/13/2013
 * 
 * Group 2
 * ITCS 3146
 * 
 * Group Project
 * MULTICS Paging Algorithm
 * 
 */


package MULTICS;

public class PageFaultHandler 
{
	private int clockHand = 0;
	
	// Called when a pagefault occurs
	public void pageFault(Page[] RAM, PageDescriptor page,SegmentDescriptor segment,boolean segmentFault)
	{
		// Determine which page to remove
		int pageToRemove = pageClock(RAM);
		
		if(segmentFault)
			System.out.println("Page Fault! - Due to Segment Fault\nPage to be removed - Segment: " +RAM[pageToRemove].returnHeldSeg().returnSegNumb()  + "      Page: " +RAM[pageToRemove].returnHeldPage().returnPageNumb() + "      Frame: "+pageToRemove);
		else
			System.out.println("Page Fault!\nPage to be removed - Segment: " +RAM[pageToRemove].returnHeldSeg().returnSegNumb()  + "      Page: " +RAM[pageToRemove].returnHeldPage().returnPageNumb() + "      Frame: "+pageToRemove);
		
		// Set old page to out of mem
		RAM[pageToRemove].returnHeldPage().setPresAbs(false); 
		
		
		// Investigate if segment is still in memory
		boolean segmentAbsent = true;
		for(PageDescriptor pageDes: RAM[pageToRemove].returnHeldSeg().returnPageTable())
		{
			// If a page is in memory then so is the segment
			if(pageDes.pageStatus())
			{
				segmentAbsent = false;
				break;
			}
						
		}
				
		// Switch segment status if needed
		if(segmentAbsent)
			RAM[pageToRemove].returnHeldSeg().updatePageStat(false);
		
		
		
		
		//  Adds new page to RAM
		RAM[pageToRemove] = new Page(pageToRemove,page,segment); 
		// Set page frame number of page causing the pagefault
		page.setFrameNumber(pageToRemove); 
		// Update segment status
		segment.updatePageStat(true);
		// Update page pres/abs bit
		page.setPresAbs(true);
		
		
		
		
	}
	
	
	// Adjusts clock hand and returns index to page to be removed
	private int pageClock(Page[] RAM)
	{
		// Keep moving hand to page can be removed
		while(true)
		{
			// Resets hand to 0 to prevent index outofbounds (Could have used modulus)
			if(clockHand == 6)
				clockHand = 0;
			
			// If rbit is 0 then the page can be removed
			if(!RAM[clockHand].returnRBit())
			{
				int replacementPage = clockHand;
				clockHand++;
				
				return replacementPage;
			}
			
			// If not removed change rbit status
			RAM[clockHand].setRBit(false);
			
			// Advance hand
			clockHand++;
			
					
		}
			
	}
	
}
